package com.uxsino.simo.query;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.Strings;
import com.uxsino.commons.utils.config.ConfigProp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.uxsino.commons.utils.config.PropElement;
import com.uxsino.reactorq.model.IndicatorValue;
import com.uxsino.simo.indicator.ListIndicator;
import com.uxsino.simo.utils.ConfigLoadingContext;

public class ListUnionQueryCombine extends QueryCombine<ListIndicator, List<Map<String, Object>>> {

    private static Logger logger = LoggerFactory.getLogger(ListUnionQueryCombine.class);

    @ConfigProp(name = "union-key")
    @JsonProperty("union-key")
    @JSONField(name = "union-key")
    private String unionKey;

    public ListUnionQueryCombine(ListIndicator resultIndicator) {
        super(resultIndicator);
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<Map<String, Object>> apply(QueryContext ctxt, List<IndicatorValue> lists) {
//        List<Map<String, Object>> result = new ArrayList<>();
//        List<Map<String, Object>> temp = new ArrayList<>();
//        Map<String, Object> resMap = new HashMap<>();
//        if (lists == null) {
//            logger.error("List<IndicatorValue> is null");
//            return result;
//        }
//        for (IndicatorValue ind : lists) {
//            if (temp.size() == 0) {
//                temp = (List<Map<String, Object>>) ind.value;
//                continue;
//            }
//            List<Map<String, Object>> list = (List<Map<String, Object>>) ind.value;
//            for (Map<String, Object> ele : temp) {
//                resMap = ele;
//                for (Map<String, Object> m : list) {
//                    if (!m.get("name").equals(ele.get("name"))) {// 此处根据name来作为合并依据，需要query中配置name的field
//                        continue;
//                    }
//                    for (Map.Entry<String, Object> entry : m.entrySet()) {
//                        Object value = entry.getValue();
//                        if (value != null || !ele.containsKey(entry.getKey())) {
//                            resMap.put(entry.getKey(), value);
//                        }
//                    }
//                }
//                result.add(resMap);
//            }
//            temp = result;
//        }
//        return result;
        List<Map<String, Object>> result = new ArrayList<>();
        if (lists == null) {
            logger.error("List<IndicatorValue> is null");
            return result;
        }
        if (lists.size() == 0) {
            return result;
        }
        result.addAll((List) lists.get(0).value);
        String uk = Strings.isNullOrEmpty(unionKey)?"name":this.unionKey;

        for (int i = 1; i < lists.size(); i++) {
            List<Map<String, Object>> list = (List<Map<String, Object>>) lists.get(i).value;
            for (Map<String, Object> resMap : result) {
                for (Map<String, Object> e : list) {
                    if (resMap.get(uk).equals(e.get(uk))) {
                        for (Map.Entry<String, Object> entry : e.entrySet()) {
                            Object value = entry.getValue();
                            if (!e.containsKey(entry.getKey()) || value != null) {
                                resMap.put(entry.getKey(), value);
                            }
                        }
                    }
                }
            }
        }

        return result;
    }

    @Override
    public void loadProp(PropElement element, ConfigLoadingContext lctxt) {
        super.loadProp(element, lctxt);
    }

    @Override
    public boolean isCustom() {
        return false;
    }

}
